package controllers

import (
	"net/http"

	"game-simple/internal/framework/system/dto"
	"game-simple/internal/framework/system/models"
	"game-simple/internal/framework/system/services"
	"game-simple/internal/infrastructure/core"

	"github.com/gin-gonic/gin"
)

// SequenceController 编号规则控制器
type SequenceController struct {
	service *services.SequenceService
}

// NewSequenceController 创建编号规则控制器
func NewSequenceController() *SequenceController {
	return &SequenceController{
		service: services.NewSequenceService(core.Get().DB.GetDB()),
	}
}

// CreateRule 创建编号规则
// @Summary 创建编号规则
// @Description 创建新的编号规则
// @Tags 编号规则
// @Accept json
// @Produce json
// @Param rule body dto.CreateSequenceRuleRequest true "编号规则信息"
// @Success 200 {object} dto.SequenceRuleResponse
// @Router /api/system/sequence-rules [post]
func (c *SequenceController) CreateRule(ctx *gin.Context) {
	var req dto.CreateSequenceRuleRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	rule, err := c.service.CreateRule(&req)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, c.toResponse(rule))
}

// UpdateRule 更新编号规则
// @Summary 更新编号规则
// @Description 更新指定编号规则
// @Tags 编号规则
// @Accept json
// @Produce json
// @Param code path string true "规则编码"
// @Param rule body dto.UpdateSequenceRuleRequest true "编号规则信息"
// @Success 200 {object} dto.SequenceRuleResponse
// @Router /api/system/sequence-rules/{code} [put]
func (c *SequenceController) UpdateRule(ctx *gin.Context) {
	code := ctx.Param("code")
	var req dto.UpdateSequenceRuleRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	rule, err := c.service.UpdateRule(code, &req)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, c.toResponse(rule))
}

// GetRule 获取编号规则
// @Summary 获取编号规则
// @Description 获取指定编号规则详情
// @Tags 编号规则
// @Produce json
// @Param code path string true "规则编码"
// @Success 200 {object} dto.SequenceRuleResponse
// @Router /api/system/sequence-rules/{code} [get]
func (c *SequenceController) GetRule(ctx *gin.Context) {
	code := ctx.Param("code")
	rule, err := c.service.GetRule(code)
	if err != nil {
		ctx.JSON(http.StatusNotFound, gin.H{"error": "编号规则不存在"})
		return
	}

	ctx.JSON(http.StatusOK, c.toResponse(rule))
}

// ListRules 列出所有编号规则
// @Summary 列出所有编号规则
// @Description 获取所有编号规则列表
// @Tags 编号规则
// @Produce json
// @Success 200 {array} dto.SequenceRuleResponse
// @Router /api/system/sequence-rules [get]
func (c *SequenceController) ListRules(ctx *gin.Context) {
	rules, err := c.service.ListRules()
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	responses := make([]dto.SequenceRuleResponse, len(rules))
	for i, rule := range rules {
		responses[i] = c.toResponse(rule)
	}

	ctx.JSON(http.StatusOK, responses)
}

// DeleteRule 删除编号规则
// @Summary 删除编号规则
// @Description 删除指定编号规则
// @Tags 编号规则
// @Produce json
// @Param code path string true "规则编码"
// @Success 200 {object} gin.H
// @Router /api/system/sequence-rules/{code} [delete]
func (c *SequenceController) DeleteRule(ctx *gin.Context) {
	code := ctx.Param("code")
	if err := c.service.DeleteRule(code); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}

// GenerateSequence 生成编号
// @Summary 生成编号
// @Description 根据规则编码生成编号
// @Tags 编号规则
// @Accept json
// @Produce json
// @Param req body dto.GenerateSequenceRequest true "生成编号请求"
// @Success 200 {object} dto.GenerateSequenceResponse
// @Router /api/system/sequence-rules/generate [post]
func (c *SequenceController) GenerateSequence(ctx *gin.Context) {
	var req dto.GenerateSequenceRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	sequence, err := c.service.GenerateSequence(req.Code)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 获取下一个序号
	nextSeq, _ := c.service.GetCurrentSequence(req.Code)

	ctx.JSON(http.StatusOK, dto.GenerateSequenceResponse{
		Code:     req.Code,
		Sequence: sequence,
		NextSeq:  nextSeq,
	})
}

// toResponse 转换为响应对象
func (c *SequenceController) toResponse(rule *models.SequenceRule) dto.SequenceRuleResponse {
	return dto.SequenceRuleResponse{
		ID:          rule.ID,
		Code:        rule.Code,
		Name:        rule.Name,
		Prefix:      rule.Prefix,
		DateFormat:  rule.DateFormat,
		SequenceLen: rule.SequenceLen,
		ResetType:   rule.ResetType,
		CurrentSeq:  rule.CurrentSeq,
		Status:      rule.Status,
		Description: rule.Description,
	}
}

